from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
import redis,random
from datetime import datetime
from .models import *
from users.tasks import send_message
from django.contrib.auth.hashers import check_password
from rest_framework_jwt.utils import jwt_payload_handler,jwt_encode_handler
from .serializer import *
import json
# Create your views here.

# 获取短信验证码
class SmsCodeView(APIView):

    def post(self, request):

        # 1. 接受前端数据
        mobile = request.data.get("mobile")
        uuid_ = request.data.get("uuid")

        # 2. 生成随机验证码
        sms_code = random.randint(1000, 99999)
        expire = 10

        print("手机号",mobile)
        print("id",uuid_)

        # 3. 给容联云发送请求
        # result = send_message(sms_code, mobile, expire)
        # 提交异步任务
        send_message.delay(sms_code, mobile, expire)

        # 4. 判断短信是否发送成功
        # if result:
        #     # 成功发送 ， 存储sms_code---->redis
        #     sms_key = "sms_%s" %uuid_
        #     redis_cli = redis.Redis(host="localhost",port=6379, password='123', db=3)
        #     redis_cli.set(sms_key, sms_code)
        #
        #     return Response({"code":200,"msg":'短信发送成功'})
        #
        # else:
        #
        #     return Response({"code":400,'msg':'短信发送失败'})

        # 存储短信验证码
        redis_cli = redis.Redis(host="localhost", port=6379, password='123', db=3)
        sms_key = "sms_%s"%uuid_
        redis_cli.set(sms_key, sms_code)
        return Response({"code": 200, 'msg': '短信已发送，请注意查收'})


# 登录的视图
class LoginCountView(APIView):
    def post(self,request):
        # 1. 接受前端的数据
        mobile = request.data.get("mobile")
        sms_code = request.data.get("code")
        username = request.data.get("username")
        password = request.data.get("password")
        uuid_ = request.data.get("uuid")

        # 2. 判断用户是否第一次登录
        user = User.objects.filter(username=username).first()
        redis_cli = redis.Redis(host="localhost", port=6379, password='123', db=3)
        sms_key = "sms_%s"%uuid_
        # 是第一次登录
        if not user:
            stored_sms_code = redis_cli.get(sms_key)
            if stored_sms_code:
                if stored_sms_code.decode() == sms_code:
                    # 用户输入的验证码 认证通过
                    User.objects.create_user(username=username, password=password, mobile=mobile, last_login=datetime.now())

                    return Response({"code":"201", "msg":"注册成功，需申请管理员权限"})

            return Response({"code": "204", "msg": "验证码过期或者错误"})


        # 不是第一次登录
        else:
            # 优先使用用户名密码登录
            if check_password(password, user.password):
                # 认证用户通过， 检查是否有权限
                if user.is_active and user.is_staff:
                    # 有权限登录站点,登录成功
                    token = self.gen_token(user)

                    # 预留的bug
                    user.last_login = datetime.now()
                    user.save()

                    # 获取用户所有的角色,
                    roles = user.role.all()
                    # 根据角色获取对应的权限, 存入redis
                    temp = []
                    for role in roles:
                        # 获取当前角色的所有权限
                        permissions = role.permission_set.all().values_list("code_name")
                        permissions_list = [i[0] for i in permissions]

                        # 权限追加
                        temp += permissions_list

                    # 权限去重
                    user_permissions_list = list(set(temp))

                    # 存储权限到redis
                    # user_permissions_uid :
                    key = "user_permissions_%s"%user.id
                    redis_cli.set(key, json.dumps(user_permissions_list))

                    # 最终返回响应
                    return Response({
                        "code": "200",
                        "msg": "登录成功，进入首页",
                        "token": token,
                        "user": user.username
                    })

                # 认证通过还没有管理员权限
                return Response({
                    "code": "206",
                    "msg": "没有管理员权限"
                })

            else:
                # 密码校验错误， 使用短线验证码 来验证当前用户， 并重置当前密码
                stored_sms_code = redis_cli.get(sms_key)
                if stored_sms_code:
                    if stored_sms_code.decode() == sms_code:
                        # 用户输入的验证码 认证通过,则重置密码
                        user.set_password(password)
                        user.save()

                        return Response({"code": "207", "msg": "密码已重置"})

                return Response({"code": "204", "msg": "验证码过期或者错误"})





    @staticmethod
    def gen_token(user):
        # 根据用户对象，生成payload数据
        payload = jwt_payload_handler(user)
        print("生成的payload数据:", payload)

        # 编码， 生成token
        token = jwt_encode_handler(payload)

        return token


# 统计用户总数
class UserCountView(APIView):
    def get(self, request):
        # 当前用户总数
        num = User.objects.all().count()
        return Response({
            "code": "200",
            "msg": '获取用户总数成功',
            "total_count": num
        })


# 统计日增用户总数
import time
class DailyAddUserView(APIView):

    def get(self,request):
        date = time.strftime("%Y-%m-%d")
        num = User.objects.filter(date_joined__contains=date).count()

        return Response({
            "code": "200",
            "msg": '获取日增用户成功',
            "total_count": num
        })

# 统计日活跃用户总数
class DailyActiveUserView(APIView):
    def get(self, request):
        data = time.strftime("%Y-%m-%d")
        num = User.objects.filter(last_login__contains=data).count()
        return Response({
            "code":'200',
            "msg": "日活跃用户总数",
            "total_count": num
        })


# 用户的视图集

from rest_framework.viewsets import ModelViewSet
from rest_framework.pagination import PageNumberPagination


# 定义分页类
class MyPagination(PageNumberPagination):
    # 默认每页显示的条数
    page_size = 5
    # 每页最大显示的条数
    max_page_size = 10

    # 根据查询字符串的关键字参数
    # 页码
    page_query_param = "page"

    # 每页展示多少条数据
    page_size_query_param = "pagesize"


# 用户信息视图集
class UserInfoViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSer

    pagination_class = MyPagination

    def create(self,request,*args,**kwargs):
        print("新增用户的信息:", request.data)

        # 实例序列化器的对象
        ser = self.get_serializer(data=request.data)

        # 验证用户信息是否满足要求
        if ser.is_valid():

            # 保存数据
            ser.save()

            return Response({"code": "200", "msg": "添加用户信息成功", "user":ser.data})

        else:

            return Response({"code": "204", "msg": "用户不符合要求"})


class UserAvatarSet(ModelViewSet):
    queryset = UserAvatar.objects.all()
    serializer_class = UserAvatarSer
    lookup_field = "pk"
    lookup_url_kwarg = "pk"


# 权限的视图集
class PermissionViewSet(ModelViewSet):
    queryset = Permission.objects.all()
    serializer_class = PermissionSer
    lookup_field = "pk"
    lookup_url_kwarg = "pk"


# 权限类型的视图集 (角色)
class PermissionTypeViewSet(ModelViewSet):
    queryset = PermissionType.objects.all()
    serializer_class = PermissionTypeSer
    lookup_field = "pk"
    lookup_url_kwarg = "pk"

    def create(self, request, *args, **kwargs):

        # 获取前端数据
        name = request.data.get("name")
        # 获取库中的角色对象
        role = PermissionType.objects.filter(name=name)
        # 判断角色是否存在 存在则不添加
        if role:
            return Response({"code":"400", "mag":"角色存在"})
        # 角色不存在就添加角色
        else:
            # 反向序列化添加角色
            role_ser = PermissionSer(data=request.data)
            # 校验数据
            if role_ser.is_valid():
                # 成功 保存数据
                role_ser.save()
                return Response({"code":"200", "msg":"添加成功"})
            else:
                # 校验失败 返回错误提示
                return Response({"code":"400", "error":role_ser.errors})


# 管理员 的视图集
class AdminInfoViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSer
    lookup_field = "pk"
    lookup_url_kwarg = "pk"

    # 重写list方法 返回管理员用户的数据
    def list(self, request, *args, **kwargs):
        # 所有用户的查询集
        users = self.get_queryset()

        # 遍历拿到每一个用户
        admin_list = []
        for user in users:
            # 当前用户的所有角色
            roles = user.role.all()

            # 判断每一个角色，是否是管理员
            for role in roles:
                if role.name == "管理员":
                    admin_list.append(user)
                    break

        # 序列化所有的管理员数据
        admin_ser = self.get_serializer(admin_list, many=True)

        return Response({
            "code": 200,
            "msg": "加载管理员数据成功",
            "admins": admin_ser.data
        })